<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../index.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        canvas {
            margin: 50px auto 0;
            display: block;
            background: yellow;
        }
    </style>
</head>
<body>
<canvas id="canvas" width="400" height="400">
    此浏览器不支持canvas
</canvas>
</body>
</html>
<script>
    const ctx = document.getElementById('canvas')

    const gl = ctx.getContext('webgl')

    // 创建着色器源码
    const VERTEX_SHADER_SOURCE = `
    attribute vec4 aPosition;
    attribute vec4 aNormal;
    varying vec4 vColor;

    uniform mat4 mat;
    void main() {
      // 定义点光源的颜色
      vec3 uPointLightColor = vec3(1.0,1.0,0.0);

      // 点光源的位置
      vec3 uPointLightPosition = vec3(-5.0,6.0,10.0);

      // 环境光
      vec3 uAmbientLightColor = vec3(0.2,0.2,0.2);

      // 物体表面的颜色
      vec4 aColor = vec4(1.0,0.0,0.0,1.0);

      // 顶点的世界坐标
      vec4 vertexPosition = mat * aPosition;

      // 点光源的方向
      vec3 lightDirection = normalize(uPointLightPosition - vec3(vertexPosition));

      // 环境反射
      vec3 ambient = uAmbientLightColor * vec3(aColor);

      // 计算入射角 光线方向和法线方向的点积
      float dotDeg = dot(lightDirection, vec3(aNormal));

      // 漫反射光的颜色
      vec3 diffuseColor = uPointLightColor * vec3(aColor) * dotDeg;

      gl_Position = vertexPosition;
      vColor = vec4(ambient + diffuseColor, aColor.a);
    }
  `; // 顶点着色器

    const FRAGMENT_SHADER_SOURCE = `
    precision lowp float;
    varying vec4 vColor;

    void main() {
      gl_FragColor = vColor;
    }
  `; // 片元着色器

    const program = initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)

    const aPosition = gl.getAttribLocation(program, 'aPosition');
    const aNormal = gl.getAttribLocation(program, 'aNormal');
    const mat = gl.getUniformLocation(program, 'mat');

    const vertices = new Float32Array([
        // 0123
        1, 1, 1,
        -1, 1, 1,
        -1,-1, 1,
        1,-1, 1,
        // 0345
        1, 1, 1,
        1,-1, 1,
        1,-1,-1,
        1, 1,-1,
        // 0156
        1, 1, 1,
        1, 1, -1,
        -1, 1,-1,
        -1, 1,1,
        // 1267
        -1, 1, 1,
        -1,1, -1,
        -1, -1,-1,
        -1,-1,1,
        // 2347
        -1,-1, 1,
        1,-1, 1,
        1,-1,-1,
        -1,-1,-1,
        // 4567
        1,-1,-1,
        1, 1,-1,
        -1, 1,-1,
        -1,-1,-1,
    ])

    const buffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
    gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(aPosition)

    // 法向量
    const normals = new Float32Array([
        0.0,0.0,1.0,0.0,0.0,1.0,0.0,0.0,1.0,0.0,0.0,1.0,
        0.0,0.0,-1.0,0.0,0.0,-1.0,0.0,0.0,-1.0,0.0,0.0,-1.0,
        -1.0,0.0,0.0,-1.0,0.0,0.0,-1.0,0.0,0.0,-1.0,0.0,0.0,
        1.0,0.0,0.0,1.0,0.0,0.0,1.0,0.0,0.0,1.0,0.0,0.0,
        0.0,1.0,0.0,0.0,1.0,0.0,0.0,1.0,0.0,0.0,1.0,0.0,
        0.0,-1.0,0.0,0.0,-1.0,0.0,0.0,-1.0,0.0,0.0,-1.0,0.0,
    ])
    const normalBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, normals, gl.STATIC_DRAW);
    gl.vertexAttribPointer(aNormal, 3, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(aNormal)

    const indeces = new Uint8Array([
        0,1,2,0,2,3,
        4,5,6,4,6,7,
        8,9,10,8,10,11,
        12,13,14,12,14,15,
        16,17,18,16,18,19,
        20,21,22,20,22,23,
    ])
    const indexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indeces, gl.STATIC_DRAW);

    const vm = getViewMatrix(3,3,5,0.0,0.0,0.0,0.0,0.6,0.0);
    const perspective = getPerspective(30, ctx.width / ctx.height, 100, 1);
    gl.enable(gl.DEPTH_TEST);
    gl.uniformMatrix4fv(mat, false, mixMatrix(perspective, vm));
    gl.drawElements(gl.TRIANGLES, indeces.length, gl.UNSIGNED_BYTE, 0);

</script>
